package main

import (
	"context"
	"fmt"
	retry "github.com/grpc-ecosystem/go-grpc-middleware/retry"
	"go-grpc-retry/proto"
	"google.golang.org/grpc"
	"google.golang.org/grpc/codes"
	"google.golang.org/grpc/credentials/insecure"
	"time"
)

func main() {
	// 创建客户端拦截器
	interceptor := func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
		start := time.Now()
		fmt.Println("客户端拦截器")
		err := invoker(ctx, method, req, reply, cc, opts...)
		fmt.Printf("耗时：%s\n", time.Since(start))
		return err
	}

	opt := grpc.WithUnaryInterceptor(interceptor)

	//********方式二;在此处配置******
	retryOpt := []retry.CallOption{
		retry.WithMax(3), //重试3次
		retry.WithPerRetryTimeout(1 * time.Second),                                // 超过1s就要重试
		retry.WithCodes(codes.Unknown, codes.DeadlineExceeded, codes.Unavailable), // 哪些状态码重试
	}

	conn, err := grpc.Dial("127.0.0.1:50052",
		opt,
		grpc.WithTransportCredentials(insecure.NewCredentials()),
		// 客户端拦截器中加入retry--》多长时间超时？重试几次？
		// 方式一：配合下面
		//grpc.WithUnaryInterceptor(retry.UnaryClientInterceptor()),

		// 方式二：配置上面
		grpc.WithUnaryInterceptor(retry.UnaryClientInterceptor(retryOpt...)),
	)

	if err != nil {
		panic("连接服务异常")
	}

	defer conn.Close()
	client := proto.NewHelloClient(conn)
	request := proto.HelloRequest{Name: "lqz"}

	// **********方式一：在此处配置重试超时时间和重试次数和错误状态码********
	//res, err := client.Hello(context.Background(),
	//	&request,
	//	retry.WithMax(3), //重试3次
	//	retry.WithPerRetryTimeout(3*time.Second), // 超过1s就要重试
	//	retry.WithCodes(codes.Unknown,codes.DeadlineExceeded,codes.Unavailable), // 哪些状态码重试
	//)

	//*****方式二;
	res, err := client.Hello(context.Background(), &request)
	if err != nil {
		panic("调用方法异常")
	}

	fmt.Println(res.Reply)
}
